package xu.htgl.service.impl;

import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xu.htgl.common.Result;
import xu.htgl.entity.Account;
import xu.htgl.entity.Admin;
import xu.htgl.mapper.AdminMapper;
import xu.htgl.service.AdminService;
import xu.htgl.utils.TokenUtils;

import java.util.List;

/**
 * 管理员业务逻辑实现类
 * 负责处理管理员账户的CRUD操作、登录认证和密码管理等核心业务
 */
@Slf4j
@Service
public class AdminServiceImpl implements AdminService {

    @Value("${security.default-password}")
    private String defaultPassword;

    @Autowired
    private AdminMapper adminMapper;

    /**
     * 查询所有管理员列表
     *
     * @param admin 查询条件对象
     * @return 包含管理员列表的操作结果
     */
    @Override
    @Transactional
    public Result selectAll(Admin admin) {
        List<Admin> admins = adminMapper.selectAll(admin);
        return Result.ok(admins);
    }

    /**
     * 分页查询管理员列表
     *
     * @param pageNum  页码
     * @param pageSize 每页数量
     * @param admin    查询条件对象
     * @return 分页信息对象
     */
    @Override
    @Transactional
    public PageInfo<Admin> page(Integer pageNum, Integer pageSize, Admin admin) {
        PageHelper.startPage(pageNum, pageSize);
        List<Admin> list = adminMapper.selectAll(admin);
        return PageInfo.of(list);
    }

    /**
     * 新增管理员账户
     *
     * @param admin 管理员实体对象
     * @return 操作结果
     */
    @Transactional
    @Override
    public Result save(Admin admin) {
        try {
            // 1. 检查用户名唯一性
            String username = admin.getUsername();
            Admin existingAdmin = adminMapper.selectByUsername(username);
            if (existingAdmin != null) {
                return Result.failed("新增失败，该用户名已存在");
            }

            // 2. 处理默认密码
            if (StrUtil.isBlank(admin.getPassword())) {
                log.info("用户密码为空，使用默认密码：{}", defaultPassword);
                admin.setPassword(defaultPassword);
            }

            // 3. 密码加密处理（使用BCrypt算法）
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String encode = bCryptPasswordEncoder.encode(admin.getPassword());
            admin.setPassword(encode);
            admin.setRole("ADMIN");

            // 4. 执行数据库插入
            int result = adminMapper.save(admin);
            return result > 0 ? Result.ok("新增成功") : Result.failed("新增失败");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.failed("新增失败，数据库操作异常");
        }
    }

    /**
     * 更新管理员信息
     *
     * @param admin 管理员实体对象（包含ID和要更新的字段）
     * @return 操作结果
     */
    @Override
    @Transactional
    public Result updata(Admin admin) {
        int result = adminMapper.update(admin);
        return result > 0 ? Result.ok("修改成功") : Result.failed("修改失败");
    }

    /**
     * 根据ID删除管理员
     *
     * @param id 管理员ID
     * @return 操作结果
     */
    @Transactional
    @Override
    public Result deleteById(Integer id) {
        int delete = adminMapper.deleteById(id);
        return delete > 0 ? Result.ok("删除成功") : Result.failed("删除失败");
    }

    /**
     * 批量删除管理员
     *
     * @param ids 管理员ID列表
     * @return 操作结果
     */
    @Override
    @Transactional
    public Result batchDelete(List<Integer> ids) {
        try {
            int result = adminMapper.batchDelete(ids);
            return result > 0 ? Result.ok("批量删除成功") : Result.failed("批量删除失败");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.failed("批量删除失败，数据库操作异常");
        }
    }

    /**
     * 管理员登录认证
     * @param account 包含用户名和密码的账户对象
     * @return 包含登录结果和Token的操作结果
     */
    @Transactional
    @Override
    public Result login(Account account) {
        // 1. 验证账号是否存在
        Admin dbAdmin = adminMapper.selectByUsername(account.getUsername());
        if (dbAdmin == null) {
            Result.failed("账号不存在");
        }

        // 2. 验证密码（使用BCrypt匹配加密密码）
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        if (!bCryptPasswordEncoder.matches(account.getPassword(), dbAdmin.getPassword())) {
            Result.failed("账号或密码错误");
        }

        // 3. 生成认证Token（格式：用户ID-角色）
        String data = dbAdmin.getId() + "-" + "ADMIN";
        String sign = dbAdmin.getPassword();
        String token = TokenUtils.createToken(data, sign);
        dbAdmin.setToken(token);

        return Result.ok(dbAdmin);
    }

    /**
     * 根据ID查询管理员
     *
     * @param id 管理员ID
     * @return 管理员实体对象
     */
    @Override
    @Transactional
    public Admin selectById(String id) {
        return adminMapper.selectById(id);
    }

    /**
     * 修改管理员密码
     *
     * @param account 包含原密码、新密码和确认密码的账户对象
     * @return 操作结果
     */
    @Override
    @Transactional
    public Result updatePassword(Account account) {
        // 1. 验证两次输入的新密码是否一致
        if (!account.getNewPassword().equals(account.getConfirmNewPassword())) {
            return Result.failed("您输入的两次密码不一致");
        }

        // 2. 获取当前登录用户信息
        Account currentUser = TokenUtils.getCurrentUser();
        if (currentUser == null) {
            return Result.failed("未获取到当前登录用户信息");
        }

        // 3. 从数据库获取当前用户的加密密码
        Admin admin = adminMapper.selectById(String.valueOf(currentUser.getId()));
        if (admin == null) {
            return Result.failed("未找到当前用户信息");
        }

        // 4. 使用 BCryptPasswordEncoder 对前端传来的原密码进行加密验证
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if (!passwordEncoder.matches(account.getPassword(), admin.getPassword())) {
            return Result.failed("原密码输入错误");
        }

        // 5. 加密并更新新密码
        String encodedNewPassword = passwordEncoder.encode(account.getNewPassword());

        // 创建仅包含密码字段的 Admin 对象用于更新
        Admin updateAdmin = new Admin();
        updateAdmin.setId(admin.getId());
        updateAdmin.setPassword(encodedNewPassword);

        // 使用更安全的更新方法，只更新密码字段
        int updateCount = adminMapper.updateById(updateAdmin);

        return updateCount > 0 ? Result.ok("密码修改成功") : Result.failed("密码修改失败");
    }

    /**
     * 单独更新管理员头像
     * @param admin 包含 id 和 avatar 的管理员对象
     * @return 影响的行数
     */
    @Override
    public Result updateAvatar(Admin admin) {
        if (admin.getId() == null || admin.getAvatar() == null) {
            return Result.failed("ID 和头像地址不能为空");
        }
        int rows = adminMapper.updateAvatar(admin);
        return rows > 0 ? Result.ok("头像更新成功") : Result.failed("头像更新失败");
    }
}